/*
 * @(#)WorkflowAttachmentContentHandler.java
 *
 * Copyright (c) 2003 DCIVision Ltd
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of DCIVision
 * Ltd ("Confidential Information").  You shall not disclose such Confidential
 * Information and shall use it only in accordance with the terms of the license
 * agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.workflow.core;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLConnection;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.impl.LogFactoryImpl;

/**
 * <p>Class Name:       WorkflowAttachmentContentHandler.java    </p>
 * <p>Description:      The class mainly handle the file type storage for Workflow attachment content.</p>
 * @author              Angus Shiu
 * @company             DCIVision Limited
 * @creation date       02/12/2003
 * @version             $Revision: 1.4 $
 */

public class WorkflowAttachmentContentHandler implements WorkflowContentStoreHandler{
  
  public static final String REVISION = "$Revision: 1.4 $";
  
  protected Log log = new LogFactoryImpl().getInstance(this.getClass());
  private DocumentProperties properties;
  private InputStream inputStream;
  /**
   * Constructor
   *
   */
  public WorkflowAttachmentContentHandler() {
    this.properties = new DocumentProperties();
  }
  /**
   * Constructor
   * @param properties The object of DocumentProperties
   * @see com.dcivision.workflow.core.DocumentProperties
   */
  public WorkflowAttachmentContentHandler(DocumentProperties properties) {
    this.properties = properties;
  }
  /**
   * @param properties
   *          The properties to set.
   */
  public void setProperties(DocumentProperties properties) {
    this.properties = properties;
  }
  /**
   * @param property  The object of string
   * @param propertyValue The object
   */
  public void setProperty(String property, Object propertyValue) {
    properties.setProperty(property, propertyValue);
  }
  /**
   * @param propertyName The key for Hashtable
   * @return object
   */
  public Object getProperty(String propertyName) {
    return properties.getProperty(propertyName);
  }
  /**
   * @return object of DocumentProperties
   */
  public DocumentProperties getProperties() {
    return properties;
  }
  /**
   * @return string
   * @see com.dcivision.workflow.core.WorkflowContentStoreHandler#FILE_NAME_PROPERTY
   */
  public String getContentType() {
    String fileName = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_NAME_PROPERTY);
    return URLConnection.guessContentTypeFromName(fileName);
  }
  /**
   * @return string of file's extension name
   * @see com.dcivision.workflow.core.WorkflowContentStoreHandler#FILE_NAME_PROPERTY
   */
  public String getExtension() {
    String fileName = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_NAME_PROPERTY);
    String extension = null;
    int position = 0;
    if ((position = fileName.lastIndexOf(".")) != -1) {
      extension = fileName.substring(position, fileName.length());
    }
    return extension;
  }
  /**
   * @return InputStream
   * @throws ContentStoreException
   */
  public InputStream readStream() throws ContentStoreException {
    String directory = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_PHYSICAL_PATH);
    String fileName = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_NAME_PROPERTY);
    
    if (directory == null || fileName == null) {
      throw new ContentStoreException();
    }
    if (directory.charAt(directory.length() - 1) != '\\' && directory.charAt(directory.length() - 1) != '/') {
      directory = directory + System.getProperty("file.separator");
    }
    File file = new File(directory + fileName);
    if (!file.exists()) {
      throw new ContentStoreException();
    }
    InputStream inputStream = null;
    try {
      inputStream = new FileInputStream(file);
    }
    catch (FileNotFoundException fnfe) {
      throw new ContentStoreException();
    }
    return inputStream;
  }
  
  public byte[] read() throws ContentStoreException {
    String directory = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_PHYSICAL_PATH);
    String fileName = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_NAME_PROPERTY);
    
    if (directory == null || fileName == null) {
      throw new ContentStoreException();
    }
    
    if (directory.charAt(directory.length() - 1) != '\\' && directory.charAt(directory.length() - 1) != '/') {
      directory = directory + System.getProperty("file.separator");
    }
    
    File file = new File(directory + fileName);
    if (!file.exists()) {
      throw new ContentStoreException();
    }
    FileInputStream fis = null;
    ByteArrayOutputStream baos = null;
    byte[] data = null;
    try {
      fis = new FileInputStream(file);
      baos = new ByteArrayOutputStream();
      
      int bufferSize = fis.available();
      byte[] buffer = new byte[bufferSize];
      int length = -1;
      
      while ((length = fis.read(buffer, 0, bufferSize)) != -1) {
        baos.write(buffer, 0, length);
      }
      
      data = baos.toByteArray();
      return data;
    } catch (IOException ioe) {
      log.error(ioe, ioe);
      throw new ContentStoreException();
    } finally {
      try { baos.close(); } catch (IOException ioe) {} finally { baos = null; }
      try { fis.close(); } catch (IOException ioe) {} finally { fis = null; }
    }
  }
  
  public void write() throws ContentStoreException {
    String directory = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_PHYSICAL_PATH);
    String fileName = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_NAME_PROPERTY);
    
    if (directory == null || fileName == null) {
      throw new ContentStoreException();
    }
    
    FileOutputStream fos = null;
    InputStream inputStream = null;
    try {
      if (directory.charAt(directory.length() - 1) != '\\' && directory.charAt(directory.length() - 1) != '/') {
        directory = directory + System.getProperty("file.separator");
      }
      inputStream = (InputStream) properties.getProperty(WorkflowContentStoreHandler.FILE_CONTENT_PROPERTY);
      fos = new FileOutputStream(directory + fileName);
      
      int bufferSize = 8192;
      byte[] buffer = new byte[bufferSize];
      int length = -1;
      
      while ((length = inputStream.read(buffer, 0, bufferSize)) != -1) {
        fos.write(buffer, 0, length);
        fos.flush();
      }
    } catch (IOException e) {
      log.error(e, e);
      throw new ContentStoreException();
    } finally {
      try { inputStream.close(); } catch (IOException ioe) {} finally { inputStream = null; }
      try { fos.close(); } catch (IOException ioe) {} finally { fos = null; }
    }
  }
  
  public void delete() throws ContentStoreException {
    String directory = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_PHYSICAL_PATH);
    String fileName = (String) properties.getProperty(WorkflowContentStoreHandler.FILE_NAME_PROPERTY);
    
    if (directory == null || fileName == null) {
      throw new ContentStoreException();
    }
    
    File f = null;
    if (directory.charAt(directory.length() - 1) != '\\' && directory.charAt(directory.length() - 1) != '/') {
      directory = directory + System.getProperty("file.separator");
    }
    f = new File(directory + fileName);
    
    if (!f.exists()) {
      throw new ContentStoreException();
    }
    if (!f.delete()) {
      // queue to schedule deleteion again, reason : FIS reading lock
    }
  }
  
  public void close() throws ContentStoreException {
  }
}